/* 
 * File:   xmcamera.cpp
 * Author: nvr
 * 
 * Created on 2015��8��13��, ����7:59
 */

#include "xmcamera.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "time.h"

struct tm timeinfo;

int RealDataCallBack(long lRealHandle, SDK_H264_FRAME_INFO *pFrameInfo, unsigned long dwUser)
{
    xmcamera* camera = (xmcamera*)dwUser;
    if (pFrameInfo->FrameType  == 0x01)
    {
        if(camera->get_pusher_handle() == 0 ) return 0;

        if(pFrameInfo && pFrameInfo->nLength)
        {
            EASY_AV_Frame   avFrame;
            memset(&avFrame, 0x00, sizeof(EASY_AV_Frame));
            avFrame.u32AVFrameFlag  =   EASY_SDK_VIDEO_FRAME_FLAG;
            avFrame.pBuffer = pFrameInfo->pContent;
            avFrame.u32AVFrameLen = pFrameInfo->nLength;
            avFrame.u32VFrameType = pFrameInfo->nSubType==0x00?EASY_SDK_VIDEO_FRAME_I:EASY_SDK_VIDEO_FRAME_P;

            timeinfo.tm_year=(pFrameInfo->nYear)%1900;
            timeinfo.tm_mon=pFrameInfo->nMonth;
            timeinfo.tm_mday=pFrameInfo->nDay;
            timeinfo.tm_hour=pFrameInfo->nHour;
            timeinfo.tm_min=pFrameInfo->nMinute;
            timeinfo.tm_sec=pFrameInfo->nSecond;
            avFrame.u32TimestampSec=mktime(&timeinfo);
//            avFrame.u32TimestampSec=mktime(pFrameInfo->nYear,pFrameInfo->nMonth,pFrameInfo->nDay,pFrameInfo->nHour,pFrameInfo->nMinute,pFrameInfo->nSecond) ;
            avFrame.u32TimestampUsec=(pFrameInfo->nTimeStamp%1000)*1000;
            EasyPusher_PushFrame(camera->get_pusher_handle(), &avFrame);
//            printf("timestamp_sec: %d, timestamp_usec= %d, ssq: %d, nFrameRate: %d\n",avFrame.u32TimestampSec, avFrame.u32TimestampUsec,pFrameInfo->nRequence,pFrameInfo->nFrameRate);
        }
    }


#if 1
    else if (pFrameInfo->FrameType  == 0x02 )
    {
        if(camera->get_pusher_handle() == 0 ) return 0;

        if(pFrameInfo && pFrameInfo->nLength)
        {
            EASY_AV_Frame   avFrame;
            memset(&avFrame, 0x00, sizeof(EASY_AV_Frame));
            avFrame.u32AVFrameFlag  =   EASY_SDK_AUDIO_FRAME_FLAG;
            avFrame.pBuffer = pFrameInfo->pContent;
            avFrame.u32AVFrameLen = pFrameInfo->nLength;
            avFrame.u32VFrameType = EASY_SDK_VIDEO_FRAME_I;
            timeinfo.tm_year=(pFrameInfo->nYear)%1900;
            timeinfo.tm_mon=pFrameInfo->nMonth;
            timeinfo.tm_mday=pFrameInfo->nDay;
            timeinfo.tm_hour=pFrameInfo->nHour;
            timeinfo.tm_min=pFrameInfo->nMinute;
            timeinfo.tm_sec=pFrameInfo->nSecond;
            avFrame.u32TimestampSec=mktime(&timeinfo);
            avFrame.u32TimestampUsec=(pFrameInfo->nTimeStamp%1000)*1000;
            EasyPusher_PushFrame(camera->get_pusher_handle(), &avFrame);
//            printf("timestamp: %d, ssq: %d,nSamplesPerSecond: %d\n",pFrameInfo->nTimeStamp,pFrameInfo->nRequence,pFrameInfo->nSamplesPerSecond);
        }   
    }
#endif
    else
//    	printf("timestamp: %d, ssq: %d, FrameType: %d ******\n", pFrameInfo->nTimeStamp, pFrameInfo->nRequence,pFrameInfo->FrameType);
    return 0;
}
// {
//     xmcamera* camera = (xmcamera*)dwUser;
//     if(camera == NULL) return 0;
//     if(camera->pusher_handle_ == NULL) return 0;

//     //if(pFrameInfo->FrameType == FRAME_VIDEO)
//     //{
//     //  printf("video lRealHandle: %x, FrameType: %d, nSubType: %d, nFrameLength: %ld, nLength: %ld\n",
//     //                              dwUser,(unsigned int)lRealHandle, pFrameInfo->FrameType, pFrameInfo->nSubType, pFrameInfo->nFrameLength, pFrameInfo->nLength);

//     //}
//     //else if(pFrameInfo->FrameType == FRAME_AUDIO)
//     //{
//     //  printf("audio lRealHandle: %x, FrameType: %d, nSubType: %d, nFrameLength: %ld, nLength: %ld\n",
//     //                      dwUser,(unsigned int)lRealHandle, pFrameInfo->FrameType, pFrameInfo->nSubType, pFrameInfo->nFrameLength, pFrameInfo->nLength);
//     //}

//     EASY_AV_Frame frame;
//     if(pFrameInfo->FrameType == FRAME_VIDEO)
//     {
//         frame.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;
//         if(pFrameInfo->nSubType == I_FRAME)
//         {
//             frame.u32VFrameType = EASY_SDK_VIDEO_FRAME_I;            
//         }
//         else
//         {
//             frame.u32VFrameType = EASY_SDK_VIDEO_FRAME_P;
//         }
//     }
//     else
//         return 0;
    
//     frame.pBuffer = pFrameInfo->pContent;
//     frame.u32AVFrameLen = pFrameInfo->nLength;
//     printf("*");
//     return EasyPusher_PushFrame(camera->get_pusher_handle(), &frame);
// }

int AbnormalCallBack(LOCAL_ALARM_MSG *pMsg, unsigned long dwUser)
{
    printf("xmcamera AbnormalCallBack, channel[%d], type[%d], status[%d]", pMsg->nChannel, pMsg->nType, pMsg->nStatus);
    return 0;
}

int __EasyPusher_Callback(int _id, EASY_PUSH_STATE_T _state, EASY_AV_Frame *_frame, void *_userptr)
{
    if (_state == EASY_PUSH_STATE_CONNECTING)               printf("__EasyPusher_Callback Connecting...\n");
    else if (_state == EASY_PUSH_STATE_CONNECTED)           printf("__EasyPusher_Callback Connected\n");
    else if (_state == EASY_PUSH_STATE_CONNECT_FAILED)      printf("__EasyPusher_Callback Connect failed\n");
    else if (_state == EASY_PUSH_STATE_CONNECT_ABORT)       printf("__EasyPusher_Callback Connect abort\n");
    else if (_state == EASY_PUSH_STATE_PUSHING)             printf("\r*");
    else if (_state == EASY_PUSH_STATE_DISCONNECTED)        printf("__EasyPusher_Callback Disconnect.\n");

    return 0;
}

xmcamera::xmcamera()
{   
    pusher_handle_ = NULL;
}

xmcamera::~xmcamera()
{
    LOCALSDK_CleanUp();
}

int xmcamera::initialize()
{
    LOCALSDK_StartUp();
	//get dvr info, must call after LOCALSDK_StartUp
	int nRet = LOCALSDK_SUCCESS;
	LOCALSDK_DEVICE_INFO_V2 g_DevInfo;
	nRet = LOCALSDK_GetDevInfo(&g_DevInfo);
	if(LOCALSDK_SUCCESS == nRet)
	{
		printf("nAlarmInNum: %d, nAlarmOutNum: %d, nAudioNum: %d, nHddNum: %d, nPlaybackNum: %d, nSubstreamNum: %d, nVideoNum: %d, szDeviceName: %s, szDeviceType: %s, uiIP: %x, usPort: %d\n",
			  g_DevInfo.nAlarmInNum, g_DevInfo.nAlarmOutNum, g_DevInfo.nAudioNum, g_DevInfo.nHddNum, g_DevInfo.nPlaybackNum,
			  g_DevInfo.nSubstreamNum, g_DevInfo.nVideoNum, g_DevInfo.szDeviceName, g_DevInfo.szDeviceType, g_DevInfo.uiIP, g_DevInfo.usPort);
	}
	else
	{
		printf("LOCALSDK_GetDevInfo Fail, error %d\n", nRet);
		return -1;
	}
    LOCALSDK_SetAbnormalCallBack(AbnormalCallBack, (long unsigned int)this);
    return 0;
}
    // Easy_U32 u32VideoCodec;         /* ��Ƶ�������� */
    // Easy_U32 u32VideoFps;           /* ��Ƶ֡�� */
    
    // Easy_U32 u32AudioCodec;         /* ��Ƶ�������� */
    // Easy_U32 u32AudioSamplerate;    /* ��Ƶ������ */

void xmcamera::start_stream_push(const char* sms_server_addr, size_t sms_port, const char* stream_name, const char* username, const char* password, size_t buffer_size,Easy_U32 u32VideoCodec,Easy_U32 u32AudioCodec,Easy_U32 u32AudioSamplerate)
{
    long channel = 0;
    LOCALSDK_RealPlayStart(0, SDK_CAPTURE_CHN_MAIN, RealDataCallBack, (unsigned long)this, &channel);
//    LOCALSDK_RealPlayStart(0, SDK_CAPTURE_CHN_2END, RealDataCallBack, (unsigned long)this, &channel);

    pusher_info_.addr = sms_server_addr;
    pusher_info_.port = sms_port;
    pusher_info_.user_name = username;
    pusher_info_.password = password;
    pusher_info_.stream_name = stream_name;
    
    pusher_handle_ = EasyPusher_Create();
    EasyPusher_SetEventCallback(pusher_handle_, __EasyPusher_Callback, 0, this);
    EASY_MEDIA_INFO_T mediainfo;
    ::memset(&mediainfo, 0x00, sizeof(EASY_MEDIA_INFO_T));

    mediainfo.u32VideoCodec = u32VideoCodec;
    mediainfo.u32AudioCodec =   u32AudioCodec;
    mediainfo.u32AudioSamplerate = 8000;
    mediainfo.u32VideoFps=25;

    EasyPusher_StartStream(pusher_handle_, (char*)sms_server_addr, sms_port, (char*)stream_name, (char*)username, (char*)password, &mediainfo, buffer_size,0);
}

Easy_Pusher_Handle xmcamera::get_pusher_handle()
{
    return pusher_handle_;
}
